
//随机生产坐标
function generateRandomCoordinate(game, existed) {
    while (true) {
        let rowIdx = Math.floor(Math.random() * game.nRows);
        let colIdx = Math.floor(Math.random() * game.nCols);
        let key = `${rowIdx},${colIdx}`;
        if (!(key in existed)) {
            return [rowIdx, colIdx];
        }
    }
}

function randomMime(game) {
    let mines = [];
    let existed = {};
    if (game.nRows <= 0 || game.nCols <= 0 || game.numOfMines < 0 || game.numOfMines > game.nRows * game.nCols) {
        throw new Error("请重新输入‘正数’");
    }//防止输入非正数
    for (let i = 0; i < game.numOfMines; i++) {
        let coordinate = generateRandomCoordinate(game, existed);
        mines.push(coordinate);
        existed[`${coordinate[0]},${coordinate[1]}`] = true;
    }
    console.log(mines);
    game.mines = mines;
}//把函数提出，方便后期维护

//点击事件函数
function handleClick(game, rowIdx, colIdx) {
    if (game.state === 0) {
        startGame(game);
    }

    if (game.state === 2 || game.state === 3) {
        return;
    }

    let { nRows, nCols, cells } = game;

    let cell = cells[rowIdx][colIdx];

    if (cell.flag) {
        cell.flag = false;
        cell.el.classList.remove("flag");
        return;
    }

    if (cell.value == -1) {
        cell.el.classList.add("exploded");
        losegame(game);
    } else if (cell.value > 0) {
        openCell(cell)
    } else if (cell.value == 0) {
        clearSafeArea(game, rowIdx, colIdx,);
    }

    checkWin(game);

}

//实现双击清雷
function handleDoubleClick(game, rowIdx, colIdx) {
    if (game.state === 0) {
        startGame(game);
    }
    if (game.state === 2 || game.state === 3) {
        return;
    }
    let cell = game.cells[rowIdx][colIdx];
    if (cell.value > 0 && cell.value <= game.numOfMines && !cell.flag && cell.open) {
        // 统计周围已标记雷的数量
        let flaggedSurroundingMines = countFlaggedSurroundingMines(game, rowIdx, colIdx);
        if (flaggedSurroundingMines === cell.value) {
            // 打开周围未标记且未打开的单元格
            openSurroundingSafeCells(game, rowIdx, colIdx);
            checkWin(game);
        }
    }
}


//统计周围标记雷的数量
function countFlaggedSurroundingMines(game, rowIdx, colIdx) {
    let count = 0;
    for (let [deltaRow, deltaCol] of directions) {
        let newRow = rowIdx + deltaRow;
        let newCol = colIdx + deltaCol;
        if (newRow < 0 || newRow >= game.nRows || newCol < 0 || newCol >= game.nCols) {
            continue;
        }
        let neighborCell = game.cells[newRow][newCol];
        if (neighborCell.flag && neighborCell.value === -1) {
            count++;
        }
    }
    return count;
}

//打开周围未标记且未打开的格子
function openSurroundingSafeCells(game, rowIdx, colIdx) {
    for (let [deltaRow, deltaCol] of directions) {
        let newRow = rowIdx + deltaRow;
        let newCol = colIdx + deltaCol;
        if (newRow < 0 || newRow >= game.nRows || newCol < 0 || newCol >= game.nCols) {
            continue;
        }
        let neighborCell = game.cells[newRow][newCol];
        if (!neighborCell.flag && !neighborCell.open) {
            handleClick(game, newRow, newCol);
        }
    }
}

function openCell(cell) {
    cell.open = true;
    cell.el.classList.add("open");
}
//判定赢
function wingame(game) {
    game.state = 2;

    clearInterval(game.intervalId);
    let el = document.querySelector(".game-info > .status")
    el.innerText = "WIN!!!";
    openAllCelss(game)
}

//判定输
function losegame(game) {
    game.state = 3;

    clearInterval(game.intervalId);
    let el = document.querySelector(".game-info > .status")
    el.innerText = "LOSS";
    openAllCelss(game)
}

//游戏结束打开全部格子
function openAllCelss(game) {
    let { cells, nRows, nCols } = game;

    for (let rowIdx = 0; rowIdx < nRows; rowIdx++) {
        for (let colIdx = 0; colIdx < nCols; colIdx++) {
            let cell = cells[rowIdx][colIdx];
            if (!cell.open) {
                openCell(cell)
            }
        }

    }
}

function startGame(game) {
    game.state = 1;

    game.intervalId = setInterval(() => {
        game.elaspead = game.elaspead + 1;
        refreshTimer(game);
    }, 1000);
}

//刷新雷数
function showRemainNum(game) {
    let remainingDiv = document.querySelector(".game-info > .remaining")
    remainingDiv.innerText = game.remainingNum;
}

//刷新计时器
function refreshTimer(game) {
    let el = document.querySelector(".game-info > .timer")
    el.innerText = game.elaspead;
}

//双击清雷
function handleFlagCell(game, rowIdx, colIdx) {
    let { nRows, nCols, cells } = game;

    if (game.state === 0) {
        startGame(game);
    }

    if (game.state === 2 || game.state === 3) {
        return;
    }

    let cell = cells[rowIdx][colIdx];

    if (cell.open) {
        return;
    }

    if (cell.flag) {
        cell.flag = false;
        cell.el.classList.remove("flag");
        game.remainingNum = game.remainingNum + 1;
        showRemainNum(game);
    } else {
        if (game.remainingNum > 0) {
            cell.flag = true;
            cell.el.classList.add("flag");
            game.remainingNum = game.remainingNum - 1;
            showRemainNum(game);
        }

    }
    checkWin(game);
}

function checkWin(game) {
    let { cells, nRows, nCols } = game;
    let clearNum = 0;
    let untouchedNum = 0;
    for (let rowIdx = 0; rowIdx < nRows; rowIdx++) {
        for (let colIdx = 0; colIdx < nCols; colIdx++) {
            let cell = cells[rowIdx][colIdx];
            if (cell.flag && cell.value === -1) {
                clearNum = clearNum + 1;
            }

            if (!cell.open) {
                untouchedNum = untouchedNum + 1
            }
        }

    }

    if (clearNum === game.numOfMines || untouchedNum === game.numOfMines) {
        wingame(game);
        return;
    }
}

//打开空白格情况
function clearSafeArea(game, rowIdx, colIdx) {
    let { nRows, nCols, cells } = game;

    let cell = cells[rowIdx][colIdx];
    if (cell.value != 0) {
        return;
    }

    cell.open = true;
    cell.el.classList.add("open");

    for (let [deltaRow, deltaCol] of directions) {
        let newRow = rowIdx + deltaRow;
        let newCol = colIdx + deltaCol;
        if (newRow < 0 || newRow >= nRows) {
            continue;
        }
        if (newCol < 0 || newCol >= nCols) {
            continue;
        }

        let neigborCell = cells[newRow][newCol];

        if (neigborCell.open || neigborCell.flag) {
            continue;
        }

        if (neigborCell.value > 0) {
            neigborCell.open = true;
            neigborCell.el.classList.add("open");
            continue;
        }

        if (neigborCell.value == 0) {
            clearSafeArea(game, newRow, newCol);
        }
    }
}

//给格子添加周边雷的个数
function countSurroundingMines(game) {

    let { nRows, nCols, cells } = game;

    for (let rowIdx = 0; rowIdx < nRows; rowIdx++) {
        for (let colIdx = 0; colIdx < nCols; colIdx++) {
            let cell = cells[rowIdx][colIdx];
            if (cell.value == -1) {
                continue;
            }

            let numMines = 0;

            for (let [deltaRow, deltaCol] of directions) {
                let newRow = rowIdx + deltaRow;
                let newCol = colIdx + deltaCol;
                if (newRow < 0 || newRow >= nRows) {
                    continue;
                }
                if (newCol < 0 || newCol >= nCols) {
                    continue;
                }

                let neigborCell = cells[newRow][newCol];

                if (neigborCell.value == -1) {
                    numMines++;
                }
            }

            cell.value = numMines;
            if (numMines == 1) {
                cell.el.classList.add("warn-1");
            } else if (numMines == 2) {
                cell.el.classList.add("warn-2");
            } else if (numMines >= 2) {
                cell.el.classList.add("warn-3");
            }


            if (numMines > 0) {
                let mineEl = cell.el.querySelector(".mine");
                mineEl.innerText = numMines;
            }
        }


    }
}


function main() {
    console.log("main");

    // 创建难度模式选择按钮的容器
    let difficultyContainer = document.createElement("div");
    difficultyContainer.style.display = "flex";
    difficultyContainer.style.gap = "10px";
    document.body.appendChild(difficultyContainer);



    // 创建简单模式按钮
    let easyButton = document.createElement("button");
    easyButton.textContent = "Easy";
    easyButton.addEventListener("click", () => {
        initGame("easy");
    });
    difficultyContainer.appendChild(easyButton);

    // 创建中等模式按钮
    let mediumButton = document.createElement("button");
    mediumButton.textContent = "Medium";
    mediumButton.addEventListener("click", () => {
        initGame("medium");
    });
    difficultyContainer.appendChild(mediumButton);

    // 创建高级模式按钮
    let hardButton = document.createElement("button");
    hardButton.textContent = "High-level";
    hardButton.addEventListener("click", () => {
        initGame("hard");
    });
    difficultyContainer.appendChild(hardButton);


}
//切换模式刷新棋盘内容
function initGame(difficulty) {
    // 清除旧的游戏板
    let tblEl = document.querySelector("#gameboard > table.mime-grid");
    if (tblEl) {
        tblEl.innerHTML = ""; // 清除表格内容
    }

    let game = {
        nRows: 0,
        nCols: 0,
        numOfMines: 0,
        elaspead: 0,
        state: 0,//0:ready,  1:  running,  2:  win,  3:lose
        remainingNum: 0,
        cells: [],
        drawGrid: function () {

            let tblEl = document.querySelector("#gameboard > table.mime-grid");
            if (tblEl) {
                tblEl.innerHTML = ""; // 清除表格内容
            }

            // ...绘制新游戏板的代码
            let cells = [];

            for (let rowIdx = 0; rowIdx < this.nRows; rowIdx++) {
                let trEl = document.createElement("tr");
                let cellRow = [];
                for (let colIdx = 0; colIdx < this.nCols; colIdx++) {
                    let tdEl = document.createElement("td");

                    let cellDiv = document.createElement("div");
                    cellDiv.className = "cell";

                    cellDiv.innerHTML = `<div class ="mine"></div> <div class="flag">&#128681;</div>`;
                    cellDiv.addEventListener("click", (e) => {
                        handleClick(game, rowIdx, colIdx);
                    });

                    cellDiv.addEventListener("contextmenu", (e) => {
                        e.preventDefault();
                        handleFlagCell(game, rowIdx, colIdx);
                    });

                    cellDiv.addEventListener("dblclick", (e) => {
                        handleDoubleClick(game, rowIdx, colIdx);
                    });

                    tdEl.append(cellDiv);
                    trEl.append(tdEl);

                    cellRow.push({
                        open: false,
                        el: cellDiv,
                    });
                }

                cells.push(cellRow);
                tblEl.append(trEl);
            }

            // 绘制雷
            for (let mine of this.mines) {
                let [rowIdx, colIdx] = mine;

                let cell = cells[rowIdx][colIdx];
                cell.value = -1;

                let mineEl = cell.el.querySelector(".mine");
                mineEl.innerHTML = "&#9762;";
            }

            this.cells = cells;
            showRemainNum(game);
            refreshTimer(game);
        }
    };

    // 根据不同难度模式设置游戏参数
    if (difficulty === "easy") {
        game.nRows = 9;
        game.nCols = 9;
        game.numOfMines = 10;
    } else if (difficulty === "medium") {
        game.nRows = 16;
        game.nCols = 16;
        game.numOfMines = 40;
    } else if (difficulty === "hard") {
        game.nRows = 16;
        game.nCols = 30;
        game.numOfMines = 99;
    }

    game.remainingNum = game.numOfMines;

    randomMime(game);
    game.drawGrid();
    countSurroundingMines(game);
}

function showRemainNum(game) {
    let remainingDiv = document.querySelector(".game-info > .remaining")
    remainingDiv.innerText = game.remainingNum;
}

let directions = [
    [-1, -1],//左上方
    [-1, 0],//正上方
    [-1, 1],//右上方
    [0, -1],//左方
    [0, 1],//右方
    [1, -1],//左下方
    [1, 0],//正下
    [1, 1],//右下

]
//固定雷位置
let mock_mines = [
    [
        4,
        1
    ],
    [
        2,
        6
    ],
    [
        8,
        0
    ],
    [
        4,
        2
    ],
    [
        8,
        1
    ],
    [
        0,
        6
    ],
    [
        1,
        3
    ],
    [
        4,
        0
    ],
    [
        0,
        1
    ],
    [
        3,
        4
    ]
]